package org.destiny.geocen;

import java.util.Random;
import java.util.TreeSet;

import org.destiny.geocen.entity.Adventurer;
import org.destiny.geocen.entity.Brick;
import org.destiny.geocen.entity.Brick.Type;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;

public class GamePane extends View {

	public static final int brickSize = 42;

	private Brick[][] brickAry;

	// private BrickSet brickSet;
	private Paint paint;

	private Adventurer character;

	public GamePane(Context context) {
		super(context);
		paint = new Paint();
		brickAry = new Brick[20][10];
		character = new Adventurer(05, 03);
		Random random = new Random();
		Type[] brickTypes = Type.getTypes();
		for (int r = 0; r < brickAry.length; r++) {
			for (int c = 0; c < brickAry[r].length; c++) {
				brickAry[r][c] = new Brick(brickTypes[random.nextInt(3)], r, c);
			}
		}
		brickAry[0][0] = null;
		setOnTouchListener(new OnTouchListener() {

			public boolean onTouch(View v, MotionEvent e) {
				int row = (int) e.getY() / (brickSize + 1);
				int col = (int) e.getX() / (brickSize + 1);
				System.out.println(row + "," + col);
				Brick brick = brickAry[row][col];
				if (brick == null)
					return true;
				hack(brickAry[row][col]);
				brick = null;
				invalidate();
				return true;
				// repaint();
			}
		});
	}

	public void setBrick(int row, int col, Brick brick) {
		brickAry[row][col] = brick;
		brick.row = row;
		brick.col = col;
	}

	@Override
	public void onDraw(Canvas cv) {
		paint.setColor(Color.GRAY);
		cv.drawRect(0, 0, getWidth(), getHeight(), paint);
		int x = 1, y = 1;
		for (int r = 0; r < brickAry.length; r++) {
			x = 1;
			for (int c = 0; c < brickAry[r].length; c++) {
				Brick b = brickAry[r][c];
				if (b != null) {
					cv.drawBitmap(b.bitmap, x, y, paint);
					if (b.mark) {
						cv.drawRect(x + 18, y + 18, x + 28, y + 28, paint);
					}
					b.searched = false;
					b.mark = false;
				}
				x += brickSize;
			}
			y += brickSize;
		}
		cv.drawBitmap(character.bitmap, character.row * brickSize, character.col * brickSize, paint);
	}

	public void searchFor(Brick brick, BrickSet brickSet) {
		if (brick == null)
			return;
		int r = brick.row;
		int c = brick.col;
		brick.searched = true;
		brick.mark = true;
		if (r > 0)
			validateSearch(brick, brickAry[r - 1][c], brickSet);
		if (c < 9)
			validateSearch(brick, brickAry[r][c + 1], brickSet);
		if (r < 19) {
			validateSearch(brick, brickAry[r + 1][c], brickSet);
			brickSet.sinkable &= calcSinkable(brick);
		} else
			brickSet.sinkable = false;
		if (c > 0)
			validateSearch(brick, brickAry[r][c - 1], brickSet);
	}

	public void validateSearch(Brick from, Brick to, BrickSet brickSet) {
		if (to == null)
			return;
		if (!to.searched) {
			to.searched = true;
			if (to.type.equals(from.type)) {
				brickSet.add(to);
				to.mark = true;
				searchFor(to, brickSet);
			}
		}
	}

	public void hack(Brick brick) {
		if (brick == null)
			return;
		int r = brick.row;
		int c = brick.col;
		Brick b;
		if (r > 0)
			validateHack(brick.type, brickAry[r - 1][c]);
		if (c < 9)
			validateHack(brick.type, brickAry[r][c + 1]);
		if (r < 19)
			validateHack(brick.type, brickAry[r + 1][c]);
		if (c > 0)
			validateHack(brick.type, brickAry[r][c - 1]);
	}

	private void validateHack(Brick.Type type, Brick brick) {
		if (brick == null)
			return;
		if (type == brick.type) {
			hack(brick);
			brickAry[brick.row][brick.col] = null;
		}
	}

	public void searchAndDelete() {

	}

	public boolean calcSinkable(Brick brick) {
		if (brick.row < 19) {
			Brick under = brickAry[brick.row + 1][brick.col];
			return (under == null || under.type == brick.type);
		} else
			return false;
	}

}

class BrickSet extends TreeSet<Brick> {
	private static final long serialVersionUID = 1L;
	boolean sinkable = true;

	public BrickSet() {
	}

}
